package com.hotel.BL;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.EntityName;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.CompositeFilterOperator;
import com.google.appengine.api.datastore.Query.Filter;
import com.google.appengine.api.datastore.Query.FilterOperator;
import com.google.appengine.api.datastore.Query.FilterPredicate;

import data.CreditCard;
import data.Guest;
import data.GuestMapping;
import data.Reservation;
import data.Salutation;
import data.passingData.GuestData;


public class GuestLogic extends AbstractBL {
	public GuestLogic(HttpServletRequest req,HttpServletResponse resp){
		this.req = req;
		this.resp = resp;
	}
	public List<Guest> GenerateGuest() {
		List<Guest> list = new ArrayList<Guest>();
		Salutation salutation = new SalutationLogic().GetSalutation(1, "Mr.");
		Guest guest = new Guest();
		guest.setSalutation(salutation);
		guest.setFirstName("Kanet");
		guest.setLastName("Sarachai");
		guest.setGender("M");
		// guest.setBirthday();
		guest.setMail("sarachai.rambopanda.kanet@gmail.com");
		guest.setNationalityString("Togo");
		guest.setIdNumber("1500900113234");
		guest.setPassportNumber("");
		guest.setDriverlicense("");
		guest.setSocialSecuritycard("");
		guest.setAddressLine1("");
		guest.setAddressLine2("");
		guest.setCountry("Thailand");
		guest.setState("cheangmai");
		guest.setCity("Fang");
		guest.setPincode("50110");
		guest.setPhone("0877260015");
		guest.setFax("053452869-1");
		guest.setCompany("automationexpert");
		guest.setDesignation("");
		guest.setOfficeAddress("");
		guest.setOfficeCountry("");
		guest.setOfficeState("");
		guest.setOfficeCity("");
		guest.setOfficePincode("");
		guest.setOfficePhone1("");
		guest.setOfficePhone2("");
		guest.setOfficeFax("");
		guest.setPreference("");
		guest.setVIP(true);
		guest.setBlackList(false);

		list.add(guest);

		return list;
	}
	
	/// Guest PassingData to show Guestlist 
	public List<GuestData> GetGuestList(List<Guest> guestId, long reservationId) throws ParseException {

		List<GuestData> list = new ArrayList<GuestData>();
		Reservation reserved =new ReservationLogic(req,resp).GetReservation(reservationId);
	
		for (Guest r : guestId) {

			GuestData gd = new GuestData();
			gd.setId(r.getId());
			gd.setName(r.getFirstName() + " "+ r.getLastName());
			if(r.getSalutation()== null)
			{
				gd.setSName("");
			}else{
				gd.setSName(r.getSalutation().getTitle());
			}
			gd.setGender(r.getGender());
			gd.setIdNumber(r.getIdNumber());
			gd.setPassportNumber(r.getPassportNumber());
			gd.setDriverlicense(r.getDriverlicense());
			gd.setSocialSecuritycard(r.getSocialSecuritycard());
			gd.setNationalityString(r.getNationalityString());
			gd.setPhone(r.getPhone());
			gd.setMail(r.getMail());
			gd.setBirthday(r.getBirthday());
			gd.setAddressLine1(r.getAddressLine1());
			gd.setAddressLine2(r.getAddressLine2());
			gd.setCity(r.getCity());
			gd.setCountry(r.getCountry());
			gd.setSName((r.getSalutation()!=null)?r.getSalutation().getTitle():null);
			gd.setPincode(r.getPincode());
			gd.setFax(r.getFax());
			gd.setState(r.getState());
			gd.setCompany(r.getCompany());
			gd.setOfficeAddress(r.getOfficeAddress());
			gd.setOfficeCity(r.getOfficeCity());
			gd.setOfficeCountry(r.getOfficeCountry());
			gd.setOfficeState(r.getOfficeState());
			gd.setOfficePincode(r.getOfficePincode());
			gd.setOfficePhone1(r.getOfficePhone1());
			gd.setOfficePhone2(r.getOfficePhone2());
			gd.setOfficeFax(r.getOfficeFax());
			gd.setOfficeEmail(r.getOfficeEmail());
			
			gd.setNote(r.getNote());
			
			gd.setResId(reserved.getId());
			gd.setResAssign(reserved.isAssign());
			gd.setResGroupId(reserved.getGroupIdNumber());
			gd.setResRoomName(reserved.getRoom().getRoomName());
			gd.setResRoomTypeName(reserved.getRoom().getRoomtype().getShortName());
			gd.setResRoomNameId(reserved.getRoom().getId());
			gd.setResRoomTypeId(reserved.getRoom().getRoomtype().getId());
			gd.setResColor(reserved.getReservationStatus().getColor());
			gd.setResReservationTitle(reserved.getReservationStatus().getTitle());
			gd.setResDate(reserved.getDate());
			gd.setResSpan(reserved.getSpan());
			gd.setGid(Long.parseLong(reserved.getGuestString()));
			list.add(gd);	
		}


		return list;
	}

	public Guest AddGuest(long salutatinId, String name, String lastName,
			String phone,  String mail)
			throws EntityNotFoundException {

		Guest guest = new Guest();

		guest.setSalutationString(Long.toString(salutatinId));
		guest.setFirstName(name);
		guest.setLastName(lastName);
		guest.setPhone(phone);
		guest.setMail(mail);
		guest.setAddressLine1("");
		guest.setAddressLine2("");
		guest.setCompany("");
		guest.setIdNumber("");
		Key k = datastore.put(guest.getEntity());
		guest.setId(k.getId());
		guest.setKey(k);
		
		return guest;
	}

	public Guest AddFullGuest(long salutatinId, String name, String lastName,
			String phone,  String mail,String address,String company)throws EntityNotFoundException {

		Guest guest = new Guest();

		guest.setSalutationString(Long.toString(salutatinId));
		guest.setFirstName(name);
		guest.setLastName(lastName);
		guest.setPhone(phone);
		guest.setMail(mail);
		guest.setAddressLine1(address);
		guest.setAddressLine2("");
		guest.setCompany(company);
		guest.setIdNumber("");
		Key k = datastore.put(guest.getEntity());
		guest.setId(k.getId());
		guest.setKey(k);
		return guest;
	}
	
	public Guest GetGuest(long id) {
		Key key = KeyFactory.createKey(EntityName.Guest, id);
		try {
			Entity lang = datastore.get(key);
			Guest c = new Guest();
			c.setEntity(lang);
			return c;
		} catch (EntityNotFoundException e) {
			return null;
		}
	}

	public List<Guest> GetAllGuest(String fristName) {
		Query q = new Query(EntityName.Guest);

		Filter filterfName = new FilterPredicate("firstName",
				FilterOperator.EQUAL, fristName);

		q.setFilter(filterfName);

		return GetList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
	}
	

	public Guest GetFristName(String fristName) {
		
		Filter filter = new FilterPredicate("firstName",FilterOperator.EQUAL,fristName);

		Query q = new Query(EntityName.Guest).setFilter(filter);
		PreparedQuery pq = datastore.prepare(q);
		try{
			Entity e = pq.asSingleEntity();
			
			Guest n = new Guest();
			n.setEntity(e);
			
			return n;
		}
		catch(Exception e) { return null;} 
	}
	
	public List<Guest> GetAllGuest() {
		Query q = new Query(EntityName.Guest);
		return GetList(datastore.prepare(q).asList(
				FetchOptions.Builder.withDefaults()));
	}

	public Guest GetUser(Entity entity) {
		Guest item = new Guest();
		item.setEntity(entity);
		return item;
	}

	public List<Guest> GetList(List<Entity> entities) {
		List<Guest> list = new ArrayList<Guest>();
		if(entities!=null)
		for (Entity e : entities) {
			Guest a = new Guest();
			a.setEntity(e);
			list.add(a);
		}
		return list;
	}

	public Guest EditName(long hotelId, long guestId, String name)
			throws EntityNotFoundException, ParseException {
		Guest g = GetGuest(guestId);
		String[] fullname = name.split("\\s");
			g.setFirstName(fullname[0]);
		if(fullname.length ==1){
			g.setLastName("");
		}else{
			g.setLastName(fullname[1]);
		}
		
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	public Guest EditAddress(long hotelId, long guestId, String addressLine1)
			throws EntityNotFoundException, ParseException {
		Guest g = GetGuest(guestId);
		g.setAddressLine1(addressLine1);
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	public Guest EditTel(long hotelId, long guestId, String tel)
			throws EntityNotFoundException, ParseException {
		Guest g = GetGuest(guestId);
		g.setPhone(tel);
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	public Guest EditCompany(long hotelId, long guestId, String company)
			throws EntityNotFoundException, ParseException {
		Guest g = GetGuest(guestId);
		g.setCompany(company);
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	public Guest EditCompanyAddress(long hotelId, long guestId, String officeAddress)
			throws EntityNotFoundException, ParseException {
		Guest g = GetGuest(guestId);
		g.setOfficeAddress(officeAddress);
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	
	public Guest EditGuestData(long hotelId,String Name,String lastName,String SName,String mail,String gender,String birthday,String nationalityString
			,String phone,String idNumber,String passportNumber,String driverlicense,String socialSecuritycard
			,String addressLine,String country,String state,String city,String pincode,String fax,String company
			,String officeAddress,String officeCountry,String officeState,String officeCity,String officePincode,String officePhone
			,String officeFax,String officeEmail,boolean isVIP,boolean isBlackList,String note,long guestId,String designation)
			throws EntityNotFoundException, ParseException {
		
		Guest g = new Guest();
		if(guestId != 0){
			 g = GetGuest(guestId);
		}
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd",
				Locale.ENGLISH);
		g.setFirstName(Name);
		g.setLastName(lastName);
		g.setSalutationString(SName);
		g.setGender(gender);
		g.setIdNumber(idNumber);
		g.setPassportNumber(passportNumber);
		g.setDriverlicense(driverlicense);
		g.setSocialSecuritycard(socialSecuritycard);
		g.setNationalityString(nationalityString);
		g.setPhone(phone);
		g.setMail(mail);
		g.setState(state);
		g.setBirthday(formatter.parse(birthday));
		g.setAddressLine1(addressLine);
		g.setCity(city);
		g.setCountry(country);
		g.setPincode(pincode);
		g.setFax(fax);
		g.setDesignation(designation);
		g.setCompany(company);
		g.setOfficeAddress(officeAddress);
		g.setOfficeCity(officeCity);
		g.setOfficeCountry(officeCountry);
		g.setOfficeState(officeState);
		g.setOfficePincode(officePincode);
		g.setOfficePhone1(officePhone);
		g.setOfficeFax(officeFax);
		g.setOfficeEmail(officeEmail);
		
		g.setNote(note);
		g.setVIP(isVIP);
		g.setBlackList(isBlackList);
		Key k = datastore.put(g.getEntity());
		g.setId(k.getId());
		g.setKey(k);

		return g;
	}
	
	public GuestData FillGuestData(Guest gs,Reservation res){
		GuestData gd = new GuestData();
		if(gs==null) return null;
		gd.setId(gs.getId());
		gd.setName(gs.getFirstName() +" "+ gs.getLastName());
		if(gs.getSalutation() != null)
			gd.setSName(gs.getSalutation().getTitle());
		gd.setPhone(gs.getPhone());
		gd.setIdNumber(gs.getIdNumber());
		gd.setResGroupId(res.getGroupIdNumber());
		gd.setResId(res.getId());
		gd.setResRoomNameId(res.getRoom().getId());
		gd.setResRoomTypeId(res.getRoomType().getId());
		gd.setResSpan(res.getSpan());
		return gd;
	}
	
	public List<CreditCard> getCreditCard(String guestId){
		Guest g = GetGuest(Long.parseLong(guestId));
		if(g.getCreditCardString()!=null){
			List<CreditCard> guestCC = g.getCreditCard();
			return guestCC;
		}else{
			return null;
		}
		
	}

	public HashMap<String,Object> DeleteGuest(long hotelId,String id) throws EntityNotFoundException{
		GuestMapping t = new GuestMappingLogic(req,resp).GetGuestMappingByGuestId(hotelId,id);
		t.setAvaliable(false);
		t.setStatus(false);
		
		Key k = datastore.put(t.getEntity());
		t.setId(k.getId());
		t.setKey(k);

		return GetGuestData(t);
	}
	
	public HashMap<String,Object> GetGuestData(GuestMapping data){
		HashMap<String, Object> hashmap = new HashMap<String, Object>();
		hashmap.put("guest", data.getGuest());
		hashmap.put("status", data.isStatus());
		return hashmap;
	}
	
	public HashMap<String,Object> ChangeStatus(long hotelId,String id) throws EntityNotFoundException{
		
		GuestMapping a = new GuestMappingLogic(req,resp).GetGuestMappingByGuestId(hotelId,id);
		if(a.isStatus() == true){
			a.setStatus(false);
		}else if(a.isStatus() == false){
			a.setStatus(true);
		}
		 
		Key k = datastore.put(a.getEntity());
		a.setId(k.getId());
		a.setKey(k);

		return GetGuestData(a);
	}
	
	public List<HashMap<String, Object>> GetAllGuest4AdminLimit(long hotelId,long offset,long line)
	{
		Query q = new Query(EntityName.GuestMapping);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return GetGuestInMapping(new GuestMappingLogic(req,resp).GetList(datastore.prepare(q).asList(FetchOptions.Builder.withLimit((int) line).offset((int)offset))));
	}
	
	public List<HashMap<String, Object>> GetGuestInMapping(List<GuestMapping> list){
		List<HashMap<String, Object>> guestlist = new ArrayList<HashMap<String, Object>>();
		
		for(int i=0;i<list.size();i++){
			guestlist.add(GetGuestData(list.get(i)));
		}
		
		return guestlist;
	}
	
	public List<GuestMapping> GetAllGuest4Admin(long hotelId)
	{
		Query q = new Query(EntityName.GuestMapping);
		
		Filter filterHotel = new FilterPredicate("hotelId",FilterOperator.EQUAL,hotelId);
		Filter filterAvaliable = new FilterPredicate("avaliable",FilterOperator.EQUAL,true);

		Filter filter = CompositeFilterOperator.and(filterHotel, filterAvaliable);
		
		q.setFilter(filter);
		
		return new GuestMappingLogic(req,resp).GetList(datastore.prepare(q).asList(FetchOptions.Builder.withDefaults()));
	}
	
	public GuestData SetToGuestData(Guest g){
		GuestData gData = new GuestData();
		if(!g.getSalutationString().equals("0")){
			gData.setSalutation(g.getSalutation().getTitle());
		}
		gData.setAddressLine1(g.getAddressLine1());
		gData.setAddressLine2(g.getAddressLine2());
		gData.setBirthday(g.getBirthday());
		gData.setCity(g.getCity());
		gData.setCompany(g.getCompany());
		gData.setDesignation(g.getDesignation());
		gData.setDriverlicense(g.getDriverlicense());
		gData.setFax(g.getFax());
		gData.setGender(g.getGender());
		gData.setId(g.getId());
		gData.setIdNumber(g.getIdNumber());
		gData.setMail(g.getMail());
		gData.setName(g.getFirstName());
		gData.setNationalityString(g.getNationalityString());
		gData.setNote(g.getNote());
		gData.setOfficeAddress(g.getOfficeAddress());
		gData.setOfficeCity(g.getOfficeCity());
		gData.setOfficeCountry(g.getOfficeCountry());
		gData.setOfficeEmail(g.getOfficeEmail());
		gData.setOfficeFax(g.getOfficeFax());
		gData.setOfficePhone1(g.getOfficePhone1());
		gData.setOfficePhone2(g.getOfficePhone2());
		gData.setOfficePincode(g.getOfficePincode());
		gData.setOfficeState(g.getOfficeState());
		gData.setPassportNumber(g.getPassportNumber());
		gData.setPhone(g.getPhone());
		gData.setPincode(g.getPincode());
		gData.setPreference(g.getPreference());
		gData.setSName(g.getLastName());
		gData.setSocialSecuritycard(g.getSocialSecuritycard());
		gData.setState(g.getState());
		return gData;
	}
}